/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.mzk.oai.repositoryManager.items;

import cz.mzk.oai.repositoryManager.AbstractEntityManager;
import cz.mzk.oai.repositoryManager.EntityNotFoundException;
import cz.mzk.oai.repositoryManager.EntityPresentException;
import cz.mzk.oai.repositoryManager.IncorrectEntityException;
import cz.mzk.oai.repositoryManager.MetadataFormat;
import cz.mzk.oai.repositoryManager.collections.CollectionEntity;
import cz.mzk.oai.repositoryManager.oaiId.OaiIdentifierEntity;
import cz.mzk.oai.repositoryManager.records.RecordEntity;
import cz.mzk.oai.repositoryManager.sets.SetEntity;
import java.util.List;
import javax.persistence.Query;

/**
 *
 * @author Martin Rehanek (rehan@mzk.cz)
 */
public class ItemManagerImpl extends AbstractEntityManager implements ItemManager {

    private static final String QUERY_FIND_BY_OAIID = "SELECT i FROM " + ItemEntity.class.getSimpleName() + " i WHERE i.oaiId = :oaiId";
    private static final String QUERY_FIND_BY_COLLECTION = "SELECT i FROM " + ItemEntity.class.getSimpleName() + " i WHERE i.collection = :collection";

    private boolean exists(OaiIdentifierEntity id) {
        Query query = getEntityManager().createQuery(QUERY_FIND_BY_OAIID);
        //query.setParameter("collection", col);
        query.setParameter("oaiId", id);
        return !super.isEmpty(query);
    }

    public ItemEntity createItem(OaiIdentifierEntity id, CollectionEntity col) throws EntityPresentException {
        if (exists(id)) {
            throw new EntityPresentException(getEntityClassName(), "oaiidId:" + id.getId());
        }
        getEntityManager().getTransaction().begin();
        ItemEntity item = new ItemEntity();
        getEntityManager().persist(item);
        CollectionEntity colManaged = getEntityManager().merge(col);
        item.setOaiId(id);
        item.setCollection(colManaged);
        col.getItems().add(item);
        getEntityManager().getTransaction().commit();
        return item;
    }

    public ItemEntity findByOaiId(OaiIdentifierEntity oaiId) throws EntityNotFoundException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public List<ItemEntity> findByCollection(CollectionEntity col) {
        String queryStr = QUERY_FIND_BY_COLLECTION;
        Query query = getEntityManager().createQuery(queryStr);
        query.setParameter("collection", col);
        List<ItemEntity> result = (List<ItemEntity>) query.getResultList();
        return result;
    }

    public List<ItemEntity> findBySetAndFormat(SetEntity set, MetadataFormat format) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public List<ItemEntity> findByFormat(MetadataFormat format) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void setCollection(ItemEntity item, CollectionEntity collection) throws EntityNotFoundException, IncorrectEntityException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void setRecord(ItemEntity item, MetadataFormat format, RecordEntity record) throws EntityNotFoundException, IncorrectEntityException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void removeItem(ItemEntity item) throws EntityNotFoundException, IncorrectEntityException {
        if (!isManagedEntity(item)) {
            throw new IncorrectEntityException(getEntityClassName(), getEntityIdString(item));
        }

        getEntityManager().getTransaction().begin();
        try {
            getEntityManager().remove(item);
        } catch (IllegalArgumentException e) {
            throw new EntityNotFoundException(getEntityClassName(), getEntityIdString(item));
        } finally {
            getEntityManager().getTransaction().commit();
        }
    }

    @Override
    protected String getEntityClassName() {
        return ItemEntity.class.getCanonicalName();
    }

    @Override
    protected String getEntityIdString(Object entity) {
        if (!(entity instanceof ItemEntity)) {
            throw new IllegalArgumentException("not instance of " + ItemEntity.class.getCanonicalName());
        }
        ItemEntity item = (ItemEntity) entity;
        StringBuilder result = new StringBuilder();
        result.append("id:").append(item.getId());
        return result.toString();
    }
}
